package pl.edu.szlif.mosm.commonlib.provider;

import java.io.IOException;

import javax.microedition.lcdui.Image;

import pl.edu.szlif.mosm.commonlib.MathSupplement;
import pl.edu.szlif.mosm.commonlib.http.GenericHTTPConnection;

public class OSMTilesProvider implements TilesProvider {

	private GenericHTTPConnection connectionStub;

	public OSMTilesProvider(GenericHTTPConnection connStub) {
		connectionStub = connStub;
	}

	public double calculateLat(double tx, double ty, int zoom) {
		return 0; // TODO implement
	}

	public double calculateLon(double tx, double ty, int zoom) {
		return 0; // TODO implement
	}

	public double calculateTileX(double lon, double lat, int zoom) {
		return ((lon + 180) / 360) * MathSupplement.pow2(zoom);
	}

	public double calculateTileY(double lon, double lat, int zoom) {
		lat *= Math.PI / 180.0f;
		return (1 - (MathSupplement.log10(Math.tan(lat) + 1 / Math.cos(lat)) / Math.PI)) / 2 * MathSupplement.pow2(zoom);
	}

	public int getMaxZoom() {
		return 18;
	}

	public void requestTile(int tx, int ty, int zoom, TilesProviderListener listener) {
		//TODO Asynchronous connection requests
		if (listener == null) {
			throw new IllegalArgumentException("A listener must be provided");
		}
		if (checkParamsTiles(tx, ty, zoom) == false) {
			listener.tileNotAvailable(tx, ty, zoom);
			return;
		}
		try {
			String url = "http://tile.openstreetmap.org/" + zoom + "/" + tx + "/" + ty + ".png";
			GenericHTTPConnection conn = connectionStub.open(url, GenericHTTPConnection.GET);
			conn.execute();
			Image img = Image.createImage(conn.getInputStream());
			listener.tileReady(tx, ty, zoom, img);
		} catch (IOException exc) {
			System.out.println(exc.getMessage());
			listener.tileNotAvailable(tx, ty, zoom);
		}
	}

	private boolean checkParamsGeo(double lon, double lat, int zoom) {
		return (lon >= -180) && (lon <= 180) && (lat >= -85.0511) && (lat <= 85.0511) && (zoom >= 0) && (zoom <= 18);
	}

	private boolean checkParamsTiles(double tx, double ty, int zoom) {
		int powzoom = MathSupplement.pow2(zoom) - 1;
		return (zoom >= 0) && (zoom <= 18) && (tx >= 0) && (tx <= powzoom) && (ty >= 0) && (ty <= powzoom);
	}

	public int getTileHeight() {
		return 256;
	}

	public int getTileWidth() {
		return 256;
	}
}
